package com.hhsj.design.pullableview.recyclerview;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;

import com.hhsj.design.pullableview.view.DefaultFooterLineView;
import com.hhsj.design.pullableview.view.DefaultLoadMoreView;
import com.hhsj.design.pullableview.view.DefaultRefreshView;
import com.hhsj.design.pullableview.FooterBackToNormalRunnable;
import com.hhsj.design.pullableview.FooterGoingToLoadMoreRunnable;
import com.hhsj.design.pullableview.HeaderBackToNormalRunnable;
import com.hhsj.design.pullableview.HeaderGoingToRefreshRunnable;
import com.hhsj.design.pullableview.view.IFooterLineView;
import com.hhsj.design.pullableview.view.ILoadMoreView;
import com.hhsj.design.pullableview.ability.IPullAble;
import com.hhsj.design.pullableview.view.IRefreshView;

import java.util.ArrayList;

public class RefreshRecycleViewPro extends RecyclerView implements IPullAble {

    private static String TAG = RefreshRecycleViewPro.class.getSimpleName();

    /**
     * 1.如果listview滑出屏幕的距离为0时，下拉时header下面的view慢慢显示出来
     * 2.如果listview滑出屏幕的距离不为0时，执行其自身的滑动
     * 3.如果正在向下显示header下面的view时，上滑view也向上隐藏，隐藏完继续listview自身的滑动
     */
    private LinearLayout mHeaderParent;
    private LinearLayout mHeaderLayout;
    private FrameLayout mRefreshParent;
    private IRefreshView mIRefreshView;


    private LinearLayout mFooterParent;
    private LinearLayout mFooterLayout;//添加footer的父布局

    private FrameLayout mFooterLineParent;//底线布局的父布局
    private IFooterLineView mIFooterLineView;

    private FrameLayout mLoadMoreParent;//底线+刷新布局的父布局
    private ILoadMoreView mILoadMoreView;

    private int mTouchSlop;
    private int mRefreshViewHeight;
    private int mCanRefreshHeight;

    //需要继续刷新的时候刷新视图的高度
    private int mContinuePullHeight;

    //上拉加载等多的视图的高度
    private int mLoadMoreViewHeight;
    private int mCanLoadMoreHeight;//可执行上拉加载更多时的高度阈值

    private float mLastX, mLastY;

    private boolean mIsAutoMoving = false;

    private boolean mIsRefreshing = false;

    private boolean mIsLoading = false;

    private boolean mIsDrag;
    //正在显示底线
    private boolean isFooterLineShowing = false;

    private ViewGroup.LayoutParams headerParams;
    private HeaderBackToNormalRunnable mBackNormalStateRunnable;
    private HeaderGoingToRefreshRunnable mBackRefreshStateRunnable;

    private ViewGroup.LayoutParams footerParams;//header refreshlayout params
    private FooterBackToNormalRunnable mFooterBackNormalStateRunnable;
    private FooterGoingToLoadMoreRunnable mFooterBackLoadMoreStateRunnable;

    private PullAbleListener mListener;
    private int refreshViewMode = REFRESH_VIEW_MODE_MID;

    private boolean supportPull = true;//是否支持弹性
    private boolean supportContinuePull = false;//支持继续下拉
    private boolean supportRefresh = false;//是否支持刷新
    private boolean supportLoadMore = false;//是否支持加载更多刷新
    private boolean supportFooterLine = false;//是否支持底线

    //RecyclerView 特有属性
    public static final int TYPE_HEADER = -3;
    public static final int TYPE_FOOTER = 5;

    public RefreshRecycleViewPro(Context context) {
        this(context, null);
    }

    public RefreshRecycleViewPro(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RefreshRecycleViewPro(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        initHeader();
        initFooter();

        ViewTreeObserver observer = mHeaderParent.getViewTreeObserver();
        if (null != observer) {
            observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    ViewTreeObserver observer = getViewTreeObserver();
                    if (null != observer) {
                        observer.removeOnGlobalLayoutListener(this);
                    }
                }
            });
        }
        addOnScrollListener(new OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
            }

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
            }
        });
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
    }

    @Override
    public void onScrolled(int dx, int dy) {
        super.onScrolled(dx, dy);
    }

    @Override
    public void addHeaderView(View v) {
        mHeaderLayout.addView(v);
    }

    @Override
    public void addFooterView(View footer) {
        mFooterLayout.addView(footer);
    }

    private void initHeader() {
        mHeaderParent = new LinearLayout(getContext());
        mHeaderParent.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
        mHeaderParent.setOrientation(LinearLayout.VERTICAL);

        mHeaderLayout = new LinearLayout(getContext());
        mHeaderLayout.setBackgroundColor(0x00000000);
        mHeaderLayout.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
        mHeaderLayout.setOrientation(LinearLayout.VERTICAL);
        mHeaderParent.addView(mHeaderLayout);

        mRefreshParent = new FrameLayout(getContext());
        mRefreshParent.setBackgroundColor(0x6600ff00);
        mRefreshParent.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 0));

        if (refreshViewMode == REFRESH_VIEW_MODE_TOP) {
            mHeaderParent.addView(mRefreshParent, 0);
        } else {
            mHeaderParent.addView(mRefreshParent);
        }
    }

    private void initFooter() {
        //添加底部布局
        mFooterParent = new LinearLayout(getContext());
        mFooterParent.setOrientation(LinearLayout.VERTICAL);
        mFooterParent.setGravity(Gravity.CENTER_HORIZONTAL);
        mFooterParent.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));

        //真的意义上的footer
        mFooterLayout = new LinearLayout(getContext());
        mFooterLayout.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
        mFooterLayout.setOrientation(LinearLayout.VERTICAL);
        mFooterParent.addView(mFooterLayout);
        //底线布局
        mFooterLineParent = new FrameLayout(getContext());
        mFooterLineParent.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        mFooterParent.addView(mFooterLineParent);

        //底线和刷新布局
        mLoadMoreParent = new FrameLayout(getContext());
        mLoadMoreParent.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 0));
        mFooterParent.addView(mLoadMoreParent);
    }


    private boolean isValidDrag(MotionEvent ev) {
        if (ev == null) {
            return false;
        }
        return Math.abs(mLastX - ev.getX()) < Math.abs(mLastY - ev.getY())
                && Math.abs(mLastY - ev.getY()) > mTouchSlop;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (mIsAutoMoving) {
            return true;
        }
        if (mIsRefreshing || mIsLoading) {
            return true;
        }
        if ((!supportRefresh || mIRefreshView == null)
                && (!supportLoadMore || mILoadMoreView == null)) {
            return super.onInterceptTouchEvent(ev);
        }
        int action = ev.getActionMasked();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                mLastX = ev.getX();
                mLastY = ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                if (isValidDrag(ev)) {
                    return true;
                }
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (mIsAutoMoving) {
            return true;
        }
        if (mIsRefreshing || mIsLoading) {
            return true;
        }
        //需要处理header view里面的显示的话，要设置param，否则给父类自己来处理
        if ((!supportRefresh || mIRefreshView == null)
                && (!supportLoadMore || mILoadMoreView == null)) {
            return super.onTouchEvent(ev);
        }

        //刷新布局的高度
        if (mRefreshViewHeight <= 0 && mIRefreshView != null) {
            mRefreshViewHeight = mIRefreshView.getRefreshHeight();
        }
        mCanRefreshHeight = mRefreshViewHeight;

        //继续下拉
        if (supportContinuePull) {
            mContinuePullHeight = mCanRefreshHeight + 240;
        }

        if (mLoadMoreViewHeight <= 0 && mILoadMoreView != null) {
            mLoadMoreViewHeight = mILoadMoreView.getLoadMoreHeight();
        }

        mCanLoadMoreHeight = mLoadMoreViewHeight;

        int action = ev.getActionMasked();

        switch (action) {
            case MotionEvent.ACTION_DOWN:
                mLastX = ev.getX();
                mLastY = ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                if (!mIsDrag && isValidDrag(ev)) {
                    mIsDrag = true;
                }

                if (mIsDrag) {
                    //下拉
                    if (ev.getY() > mLastY) {
                        //到顶
                        if (mHeaderParent.getTop() == 0) {
                            if ((supportRefresh && mIRefreshView != null)) {
                                moveHeaderLayout(ev.getY() - mLastY);
                                return true;
                            } else if (supportPull) {
                                moveHeaderLayout(ev.getY() - mLastY);
                                return true;
                            }
                        }
                    }
                    //上滑
                    else if (mLastY > ev.getY()) {
                        Log.e("HHSJHHSJ", "abc mFootLineLoadMoreParent.getBottom = " + mLoadMoreParent.getBottom());
                        Log.e("HHSJHHSJ", "abc getMeasuredHeight = " + getMeasuredHeight());
                        //到底
                        if (isSlideToBottom()) {
                            if ((supportLoadMore && mILoadMoreView != null)) {
                                moveFooterLayout(mLastY - ev.getY());
                                return true;
                            }
                        }
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                Log.e("HHSJHHSJ", "ACTION_UP");
                mIsDrag = false;
                if (mHeaderParent.getTop() == 0) {
                    if ((supportRefresh && mIRefreshView != null)) {
                        if (headerParams == null) {
                            headerParams = mRefreshParent.getLayoutParams();
                        }
                        if (headerParams.height <= 0) {
                            break;
                        }
                        //松开手指，后如果高度不够，回弹，高度够，执行刷新
                        boolean canRefresh = headerParams.height >= mCanRefreshHeight;
                        if (!canRefresh) {
                            headerBackNormal(headerParams.height);
                        } else {
                            boolean canContinuePull = supportContinuePull && headerParams.height >= mContinuePullHeight;
                            if (canContinuePull) {
                                if (null != mListener && mListener.onContinuePullAction()) {
                                    headerBackNormal(headerParams.height);
                                }
                            } else {
                                startRefreshHeight(headerParams.height, mCanRefreshHeight);
                            }
                        }
                    } else if (supportPull) {
                        headerBackNormal(headerParams.height);
                    }

                }

                //上拉加载更多，换个思路，用间距
                else if (isSlideToBottom()) {
                    Log.e("HHSJHHSJ", "ACTION_UP SlideToBottom");
                    //最后一个可见
                    if ((supportLoadMore && mILoadMoreView != null)) {
                        if (footerParams == null) {
                            footerParams = (LinearLayout.LayoutParams) mLoadMoreParent.getLayoutParams();
                        }
                        if (footerParams.height == 0) {
                            break;
                        }
                        //松开手指，后如果高度不够，回弹，高度够，执行刷新
                        boolean canLoadMore = footerParams.height >= mCanLoadMoreHeight;
                        if (!canLoadMore) {
                            Log.e("HHSJHHSJ", "ACTION_UP footerBackNormal");
                            footerBackNormal(footerParams.height);
                        } else {
                            Log.e("HHSJHHSJ", "ACTION_UP startLoadMoreHeight");
                            startLoadMoreHeight(footerParams.height, mCanLoadMoreHeight);
                        }
                    } else if (supportPull) {
                        footerBackNormal(footerParams.height);
                    }
                }
                break;
        }
        return super.onTouchEvent(ev);
    }

    private void headerBackNormal(int currentHeight) {
        int duration = (int) Math.min(currentHeight / (float) mCanRefreshHeight * 500, 200);
        if (mBackNormalStateRunnable == null) {
            mBackNormalStateRunnable = new HeaderBackToNormalRunnable(mRefreshParent) {

                @Override
                public void onHeaderBackNormalStart() {

                }

                @Override
                protected void onHeaderBackNormalCompleted() {
                    mIsRefreshing = false;
                    if (mIRefreshView != null) {
                        mIRefreshView.updateText("下拉刷新");
                        mIRefreshView.stopAnim();
                    }
                }

                @Override
                public void updateHeaderLayoutHeight(int movedHeight) {
                    updateRefreshLayoutHeight(movedHeight);
                }
            };
        }
        mBackNormalStateRunnable.start(duration);
    }

    private void footerBackNormal(int currentHeight) {
        footerBackNormalImmediately(currentHeight, false);
    }

    private void footerBackNormalImmediately(int currentHeight, boolean immediately) {
        if (immediately) {
            mIsLoading = false;
            if (mILoadMoreView != null) {
                mILoadMoreView.updateText("上拉加载更多");
                mILoadMoreView.stopAnim();
            }
            updateLoadLayoutHeight(0);
        } else {
            int duration = (int) Math.min(currentHeight / (float) mCanLoadMoreHeight * 500, 200);
            if (mFooterBackNormalStateRunnable == null) {
                mFooterBackNormalStateRunnable = new FooterBackToNormalRunnable(mLoadMoreParent) {

                    @Override
                    public void onFooterBackNormalStart() {
                        mIsAutoMoving = true;
                    }

                    @Override
                    protected void onFooterBackNormalCompleted() {
                        mIsAutoMoving = false;
                        mIsLoading = false;
                        if (mILoadMoreView != null) {
                            mILoadMoreView.updateText("上拉加载更多");
                            mILoadMoreView.stopAnim();
                        }
                    }

                    @Override
                    public void updateFooterLayoutHeight(int movedHeight) {
                        updateLoadLayoutHeight(movedHeight);
                    }
                };
            }
            mFooterBackNormalStateRunnable.start(duration);
        }
    }

    /**
     * 弹到开始刷新的高度
     */
    private void startRefreshHeight(int currentHeight, int targetHeight) {
        int duration = (int) Math.min(currentHeight / (float) mCanLoadMoreHeight * 500, 200);
        if (mBackRefreshStateRunnable == null) {
            mBackRefreshStateRunnable = new HeaderGoingToRefreshRunnable(
                    mRefreshParent,
                    targetHeight) {

                @Override
                public void onToRefresh() {

                }

                @Override
                public void updateLayoutHeight(int movedHeight) {
                    updateRefreshLayoutHeight(movedHeight);
                }

                @Override
                public void doRefresh() {
                    mIsRefreshing = true;
                    mIRefreshView.updateText("正在刷新");
                    mIRefreshView.startAnim();
                    if (mListener != null) {
                        mListener.doRefresh();
                    }
                }
            };
        }
        mBackRefreshStateRunnable.start(duration);
    }

    /**
     * 当前高度回弹到开始刷新的高度
     *
     * @param currentHeight 当前高度
     * @param targetHeight  目标高度
     */
    private void startLoadMoreHeight(int currentHeight, int targetHeight) {
        int duration = (int) Math.min(currentHeight / (float) mCanLoadMoreHeight * 500, 200);
        if (mFooterBackLoadMoreStateRunnable == null) {
            mFooterBackLoadMoreStateRunnable = new FooterGoingToLoadMoreRunnable(
                    mLoadMoreParent,
                    targetHeight) {

                @Override
                public void onToLoad() {

                }

                @Override
                public void updateLayoutHeight(int movedHeight) {
                    updateLoadLayoutHeight(movedHeight);
                }

                @Override
                public void doLoadMore() {
                    mIsLoading = true;
                    mILoadMoreView.updateText("正在加载");
                    mILoadMoreView.startAnim();
                    if (mListener != null) {
                        mListener.doLoadMore();
                    }
                }
            };
        }
        mFooterBackLoadMoreStateRunnable.start(duration);
    }

    /**
     * 根据move事件y的距离更新刷新布局的layoutparam的height
     *
     * @param eventDeltaY move事件的y方向距离
     */
    private void moveHeaderLayout(float eventDeltaY) {
        float changeHeight = (float) Math.pow(eventDeltaY, 0.85);
        headerParams = mRefreshParent.getLayoutParams();
        headerParams.height = (int) changeHeight;
        if (supportRefresh && mIRefreshView != null) {
            if (supportContinuePull) {
                if (headerParams.height > mContinuePullHeight) {
                    mIRefreshView.updateText("继续下拉进入特卖场");
                } else if (headerParams.height > mCanRefreshHeight) {
                    mIRefreshView.updateText("松开刷新");
                } else {
                    mIRefreshView.updateText("下拉刷新");
                }
            } else {
                if (headerParams.height > mCanRefreshHeight) {
                    mIRefreshView.updateText("松开刷新");
                } else {
                    mIRefreshView.updateText("下拉刷新");
                }
            }
        }
        mRefreshParent.requestLayout();
    }


    /**
     * 根据move事件y的距离更新刷新布局的LayoutParams的height
     *
     * @param eventDeltaY move事件的y方向距离
     */
    private void moveFooterLayout(float eventDeltaY) {
        float changeHeight = (float) Math.pow(eventDeltaY, 0.85);

        mILoadMoreView.getLoadMoreView().setVisibility(VISIBLE);

        footerParams = mLoadMoreParent.getLayoutParams();
        //保存上次
        int lastHeight = footerParams.height;
        footerParams.height = (int) changeHeight;
        if (footerParams.height > mCanLoadMoreHeight) {
            mILoadMoreView.updateText("松开加载更多");
        } else {
            mILoadMoreView.updateText("上拉加载更多");
        }
        mLoadMoreParent.requestLayout();
        //由于高度变化了，导致canScrollVertically(1) 为true，所以需要先滑到底
        scrollBy(0, (int) (changeHeight - lastHeight));
    }


    /**
     * 更新刷新视图高度
     *
     * @param height
     */
    private void updateRefreshLayoutHeight(int height) {
        headerParams = mRefreshParent.getLayoutParams();
        headerParams.height = height;
        mRefreshParent.requestLayout();
    }

    /**
     * 更新刷新视图高度
     *
     * @param height
     */
    private void updateLoadLayoutHeight(int height) {
        footerParams = mLoadMoreParent.getLayoutParams();
        footerParams.height = height;
        mFooterParent.requestLayout();
    }


    @Override
    public void setElasticEnable(boolean elasticEnable) {
        this.supportPull = elasticEnable;
    }

    @Override
    public boolean isElasticEnable() {
        return supportPull;
    }

    @Override
    public void setPullDownAbleListener(PullDownAbleListener listener) {

    }

    @Override
    public void setContinuePullEnable(boolean continuePullEnable) {
        supportContinuePull = continuePullEnable;
    }

    @Override
    public boolean isContinuePullEnable() {
        return supportContinuePull;
    }

    //是否支持刷新
    public void setRefreshEnable(boolean refreshEnable) {
        supportRefresh = refreshEnable;
        if (supportRefresh) {
            mHeaderParent.setMinimumHeight(1);
        } else {
            mHeaderParent.setMinimumHeight(0);
        }
        updateHeaderRefreshView();
    }

    //添加刷新控件
    private void updateHeaderRefreshView() {
        if (!supportRefresh) {
            return;
        }
        if (mIRefreshView == null) {
            addRefreshView(null, 0);
        } else {
            if (mIRefreshView.getRefreshView() != null) {
                if (mIRefreshView.getRefreshView().getParent() != null) {
                    ((ViewGroup) mIRefreshView.getRefreshView().getParent())
                            .removeView(mIRefreshView.getRefreshView());
                }
                mRefreshParent.addView(mIRefreshView.getRefreshView());
                mHeaderParent.requestLayout();
            }
        }
    }

    @Override
    public boolean isRefreshEnable() {
        return supportRefresh;
    }

    @Override
    public void setLoadMoreEnable(boolean loadMoreEnable) {
        supportLoadMore = loadMoreEnable;
        if (supportLoadMore) {
            mFooterParent.setMinimumHeight(1);
        } else {
            mFooterParent.setMinimumHeight(0);
        }
        updateFooterLoadMoreView();
    }

    private void updateFooterLoadMoreView() {
        if (!supportLoadMore) {
            return;
        }
        if (mILoadMoreView == null) {
            setLoadMoreView(null, 0);
        } else {
            if (null != mILoadMoreView.getLoadMoreView().getParent()) {
                ((ViewGroup) mILoadMoreView.getLoadMoreView().getParent())
                        .removeView(mILoadMoreView.getLoadMoreView());
            }
            mLoadMoreParent.addView(mILoadMoreView.getLoadMoreView());
        }
        mFooterLayout.requestLayout();
    }

    @Override
    public boolean isLoadMoreEnable() {
        return supportLoadMore;
    }


    //添加刷新控件
    @Override
    public void addRefreshView(IRefreshView view, int refreshHeight) {
        if (!supportRefresh) {
            return;
        }

        if (mRefreshParent.getChildCount() > 0) {
            mRefreshParent.removeAllViews();
        }

        mIRefreshView = (view == null ? getDefaultRefreshView() : view);

        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mIRefreshView.getRefreshView().getLayoutParams();

        if (params == null) {
            throw new IllegalArgumentException("view must setLayoutParams with FrameLayout.LayoutParams");
        }

        if (params.height == LayoutParams.WRAP_CONTENT || params.height == LayoutParams.MATCH_PARENT) {
            params.height = refreshHeight;
        }

        params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
        mRefreshParent.addView(mIRefreshView.getRefreshView());
        mHeaderParent.requestLayout();

    }

    @Override
    public void setLoadMoreView(ILoadMoreView iLoadMoreView, int defaultFooterHeight) {
        if (!supportLoadMore) {
            return;
        }

        mILoadMoreView = (null != iLoadMoreView ? iLoadMoreView : getDefaultFooterView());

        final View footerView = mILoadMoreView.getLoadMoreView();
        if (footerView.getParent() != null) {
            ((ViewGroup) footerView.getParent()).removeView(footerView);
        }

        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mILoadMoreView.getLoadMoreView().getLayoutParams();
        if (params == null) {
            throw new IllegalArgumentException("view must setLayoutParams with FrameLayout.LayoutParams");
        }

        if (params.height == LayoutParams.MATCH_PARENT || params.height == LayoutParams.WRAP_CONTENT) {
            params.height = defaultFooterHeight;
        }

        params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;

        if (mLoadMoreParent.getChildCount() > 0) {
            mLoadMoreParent.removeAllViews();
        }
        mLoadMoreParent.addView(footerView);
        mFooterParent.requestLayout();
    }

    //底线在刷新之上
    @Override
    public void addFooterLineView(IFooterLineView iFooterLineView) {
        if (!supportFooterLine) {
            return;
        }
        mIFooterLineView = (null == iFooterLineView ? getDefaultFooterLineView() : iFooterLineView);
        mFooterLineParent.removeAllViews();
        mFooterLineParent.addView(mIFooterLineView.getFootLineView());
    }

    //设置位置
    public void setRefreshViewMode(int mode) {
        if (mode != refreshViewMode) {
            if (mode == REFRESH_VIEW_MODE_MID || mode == REFRESH_VIEW_MODE_TOP) {
                refreshViewMode = mode;
                resetHeaderRefreshViewPosition();
            } else {
                Log.e(TAG, "无效的刷新控件位置");
            }
        }
    }

    private void resetHeaderRefreshViewPosition() {
        if (mHeaderParent == null || mHeaderParent.getChildCount() != 2) {
            return;
        }
        if (refreshViewMode == REFRESH_VIEW_MODE_TOP) {
            if (mHeaderParent.getChildAt(0) == mHeaderLayout) {
                mHeaderParent.removeView(mHeaderLayout);
                mHeaderParent.addView(mHeaderLayout);
            }
        } else {
            if (mHeaderParent.getChildAt(1) == mHeaderLayout) {
                mHeaderParent.removeView(mHeaderLayout);
                mHeaderParent.addView(mHeaderLayout, 0);
            }
        }
    }

    @Override
    public int getRefreshViewMode() {
        return refreshViewMode;
    }

    @Override
    public void setFooterLineEnable(boolean footerLineEnable) {
        if (supportFooterLine != footerLineEnable) {
            supportFooterLine = footerLineEnable;
            updateFooterLineView();
        }
    }

    /**
     * 更新底线布局
     * 条件：支持底线，是否显示底线
     */
    private void updateFooterLineView() {
        if (!supportFooterLine) {
            isFooterLineShowing = false;
            if (mIFooterLineView != null) {
                mIFooterLineView.getFootLineView().setVisibility(GONE);
            }
        } else {
            if (mIFooterLineView == null) {
                addFooterLineView(null);
            }
            mIFooterLineView.getFootLineView().setVisibility(isFooterLineShowing ? VISIBLE : GONE);
        }
        mFooterLineParent.requestLayout();
    }

    @Override
    public boolean isFooterLineEnable() {
        return supportFooterLine;
    }

    @Override
    public void showFooterLine(boolean show) {
        if (supportFooterLine) {
            isFooterLineShowing = show;
            if (null != mIFooterLineView) {
                mIFooterLineView.getFootLineView().setVisibility(isFooterLineShowing ? VISIBLE : GONE);
            }
        }
    }

    @Override
    public boolean isFooterLineShowing() {
        return supportFooterLine && isFooterLineShowing;
    }


    @Override
    public void setFooterLineEnableAndShow() {

    }

    @Override
    public void setLoadMoreViewBgColor(int colorInt) {
        mLoadMoreParent.setBackgroundColor(colorInt);
    }

    @Override
    public void setLoadMoreDisableAndShowFooterLine() {
        if (supportLoadMore) {
            return;
        }
        //不支持
        if (!supportFooterLine) {
            return;
        }
        isFooterLineShowing = true;
    }

    @Override
    public IFooterLineView getFooterLineView() {
        return mIFooterLineView;
    }

    @Override
    public void setPullAbleListener(PullAbleListener listener) {
        mListener = listener;
    }


    @Override
    public void stopRefresh() {
        if (mIRefreshView != null) {
            mIRefreshView.updateText("刷新完成");
            mIRefreshView.stopAnim();
        }
        headerBackNormal(headerParams.height);
    }

    @Override
    public void stopLoadMore() {
        if (isFooterLineShowing) {
            mIsLoading = false;
            if (mILoadMoreView != null) {
                mILoadMoreView.getLoadMoreView().setVisibility(GONE);
            }
            if (mIFooterLineView != null) {
                mIFooterLineView.getFootLineView().setVisibility(VISIBLE);
            }
            mLoadMoreParent.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
            mLoadMoreParent.requestLayout();
        } else {
            if (mILoadMoreView != null) {
                mILoadMoreView.updateText("刷新完成");
                mILoadMoreView.stopAnim();
            }
            footerBackNormalImmediately(footerParams.height, true);
        }
    }

    private IFooterLineView getDefaultFooterLineView() {
        return new DefaultFooterLineView(getContext());
    }

    private ILoadMoreView getDefaultFooterView() {
        return new DefaultLoadMoreView(getContext());
    }

    private IRefreshView getDefaultRefreshView() {
        return new DefaultRefreshView(getContext());
    }

    /**
     * 是否到底
     *
     * @return
     */
    private boolean isSlideToBottom() {
        boolean isBottom = !canScrollVertically(1);
        Log.e("HHSJHHSJ", "ACTION_UP isBottom = " + isBottom);
        return isBottom;
    }


    @Override
    public void setAdapter(@Nullable Adapter adapter) {
        ArrayList<View> headerViews = new ArrayList<>();
        headerViews.add(mHeaderParent);
        ArrayList<View> footerViews = new ArrayList<>();
        footerViews.add(mFooterParent);
        MyWrapAdapter adapter1 = new MyWrapAdapter(adapter, headerViews, footerViews);
        super.setAdapter(adapter1);
    }

    @Override
    public void setLayoutManager(@Nullable LayoutManager layout) {
        if (layout instanceof GridLayoutManager) {
            ((GridLayoutManager) layout).setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    int type = getAdapter().getItemViewType(position);
                    return type == TYPE_HEADER
                            || type == TYPE_FOOTER
                            ? ((GridLayoutManager) layout).getSpanCount() : 1;
                }
            });
        }
        super.setLayoutManager(layout);
    }

    private static class MyWrapAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

        ArrayList<View> headerViews = new ArrayList<>();
        ArrayList<View> footViews = new ArrayList<>();
        RecyclerView.Adapter adapter;

        MyWrapAdapter(@Nullable RecyclerView.Adapter adapter, ArrayList<View> headerViews, ArrayList footViews) {
            this.adapter = adapter;
            if (headerViews != null && headerViews.size() > 0) {
                this.headerViews.addAll(headerViews);
            }
            if (footViews != null && footViews.size() > 0) {
                this.footViews.addAll(footViews);
            }
        }

        @Override
        public void onViewAttachedToWindow(@NonNull ViewHolder holder) {
            ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
            if (lp instanceof StaggeredGridLayoutManager.LayoutParams) {
                StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;
                p.setFullSpan(holder.getItemViewType() == TYPE_HEADER || holder.getItemViewType() == TYPE_FOOTER);
            }
        }


        @NonNull
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            //头部item
            if (viewType == TYPE_HEADER && headerViews.size() > 0) {
                return new RecyclerView.ViewHolder(headerViews.get(0)) {
                };
            }
            //尾部item
            else if (viewType == TYPE_FOOTER && footViews.size() > 0) {
                return new RecyclerView.ViewHolder(footViews.get(0)) {
                };
            }
            return adapter.onCreateViewHolder(parent, viewType);
        }

        @Override
        public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
            Log.e("HHSJHHSJ", "position = " + position);
            if (position >= 0 && position < headerViews.size()) {
                return;
            }

            if (adapter != null) {
                int p = position - headerViews.size();
                if (p < getItemCount() - headerViews.size() - footViews.size()) {
                    adapter.onBindViewHolder(holder, p);
                }
            }
        }

        @Override
        public int getItemViewType(int position) {
            if (position >= 0 && position < headerViews.size()) {
                //如果是头部则返回一个不可用的标识,表示这是头部item
                return TYPE_HEADER;
            }

            if (adapter != null) {
                int p = position - headerViews.size();
                if (p < adapter.getItemCount()) {
                    return adapter.getItemViewType(p);
                }
            }

            Log.e("HHSJHHSJ", "Footer 可见了");
            return TYPE_FOOTER;//默认返回表示是尾部的item
        }

        @Override
        public int getItemCount() {
            int count = headerViews.size() + footViews.size();
            if (adapter != null) {
                count += adapter.getItemCount();
            }
            return count;
        }

    }

}